package com.qfmy.app.service.impl.community;

import com.qfmy.app.config.ThreadPoolConfig;
import com.qfmy.app.mapper.community.PostMapper;
import com.qfmy.app.service.community.PostService;
import com.qfmy.app.vo.community.PostVo;
import com.qfmy.common.exception.BaseException;
import com.qfmy.common.login.LoginUser;
import com.qfmy.common.login.LoginUserHolder;
import com.qfmy.common.result.ResultCodeEnum;
import com.qfmy.model.entity.community.Post;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;

/**
 * @author 清风明月
 * @Package com.qfmy.app.service.impl.community
 * @date 2025/4/16
 * @description 帖子的服务类
 */
@Service
@SuppressWarnings("all")
public class PostServiceImpl implements PostService {

    /**
     * 注入mapper
     */
    @Autowired
    private PostMapper postMapper;
    /**
     * 注入redisTemplate
     */
    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 添加帖子
     * @param post
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void add(@NotNull Post post) {
        //获取当前用户id
        Integer userId = getUserId();
        //设置用户id
        post.setUserId(userId);
        postMapper.insert(post);
    }

    /**
     * 获取帖子列表
     * @param pageNum
     * @param size
     * @return
     */
    @Override
    public List<PostVo> list(Integer pageNum, Integer size) {
        //计算分页
        int start = getStart(pageNum, size);
        //获取用户id
        Integer userId = getUserId();
        // 生成缓存键
        String cacheKey = generateCacheKey(pageNum, size);
        // 从缓存中获取数据
        List<PostVo> fromCache = getFromCaches(cacheKey);
        if(fromCache != null)
        {
            return fromCache;
        }
        //分页获取数据
        List<Post> posts = postMapper.list(start, size,userId);
        //对数据进行拷贝
        List<PostVo> postVos = CopyPost(posts);
       //异步缓存数据
        CompletableFuture.runAsync(() -> redisTemplate.opsForValue().set(cacheKey,postVos,1, TimeUnit.HOURS), ThreadPoolConfig.executorService);
        return postVos;
    }

    /**
     *
     * @param cacheKey
     * @return
     */
    @Nullable
    @Contract(pure = true)
    private List<PostVo> getFromCaches(String cacheKey) {
        List<PostVo> fromCache = (List<PostVo>) redisTemplate.opsForValue().get(cacheKey);
        //判断是否有数据
        if(fromCache != null && fromCache.size() > 0)
        {
            return fromCache;
        }
        return null;
    }

    /**
     * 生成缓存键
     * @param pageNum 当前页码
     * @param size 每页大小
     * @return 缓存键
     */
    @NotNull
    @Contract(pure = true)
    private String generateCacheKey(int pageNum, int size) {
        return String.format("novel:all:%d:%d", pageNum, size);
    }


    /**
     * 对数据进行拷贝
     * @param posts
     * @return
     */
    @Nullable
    @Contract(pure = true)
    private List<PostVo> CopyPost(List<Post> posts) {
        //判断是否有数据
        if(posts == null || posts.size() == 0)
        {
            return new ArrayList<>();
        }
        //创建集合
        List<PostVo> postVos = new ArrayList<>();
        //拷贝数据
        for(var post : posts)
        {
            //拷贝数据
            PostVo postVo = new PostVo();
            BeanUtils.copyProperties(post,postVo);
            //获取图片
            String image = post.getImage();
            //判断是否为空
            if(image != null && !image.equals(""))
            {
                //对图片进行分割用逗号进行分割
                String[] split = image.split(",");
                //设置图片
                postVo.setImage(split);
            }
            postVos.add(postVo);
        }
        return postVos;
    }

    /**
     * 获取分页的起始位置
     * @param pageNum
     * @param size
     * @return
     */
    private int getStart(Integer pageNum, Integer size) {
        pageNum = Math.max(1, pageNum != null ? pageNum : 1);
        size = size != null ? size : 10;
        return 0;
    }

    /**
     * 获取当前用户id
     * @return
     */
    private Integer getUserId() {
        LoginUser loginUser = LoginUserHolder.getLoginUser();
        //判断是否登录
        if(loginUser == null)
        {
            throw new BaseException(ResultCodeEnum.TOKEN_INVALID);
        }
        return loginUser.getUserId();
    }
}
